/**
 * Copyright 2014-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.upb.webserver.datafetcher.trans;

import com.upb.webserver.common.exception.WebServerException;
import com.upb.webserver.common.returncode.ConstantCode;
import com.upb.webserver.dao.entity.TbTransAudit;
import com.upb.webserver.dao.entity.TbTransAuditExample;
import com.upb.webserver.dao.mapper.TbTransAuditMapper;
import com.upb.webserver.datafetcher.trans.entity.TransAuditInfo;
import com.upb.webserver.datafetcher.trans.enums.AuditStatus;
import com.upb.webserver.datafetcher.trans.enums.AuditType;
import java.util.Date;
import java.util.List;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * service of Keywords.
 */
@Log4j2
@Service
public class TransAuditService {

    @Autowired
    private TbTransAuditMapper transAuditMapper;

    /**
     * add a new transAuditInfo
     */
    public TbTransAudit newAuditInfo(TransAuditInfo transAuditInfo) {
        log.debug("start newAuditInfo transAuditInfo:{}", transAuditInfo);
        // check param
        if (!AuditType.isInclude(transAuditInfo.getType())) {
            log.error("invalid audit type:{}", transAuditInfo.getType());
            throw new WebServerException(ConstantCode.INVALID_AUDIT_TYPE);
        }
        if (transAuditInfo.getType() == AuditType.KEYWORD.getValue()
                && StringUtils.isBlank(transAuditInfo.getKeyword())) {
            log.error("keyword can not be empty when audit type is:{}", transAuditInfo.getType());
            throw new WebServerException(ConstantCode.KEYWORD_ID_EMPTY);
        }
        TbTransAudit tbRecord = getAuditInfoByTxHash(transAuditInfo.getTxHash());
        if (tbRecord != null) {
            throw new WebServerException(ConstantCode.AUDIT_EXISTS);
        }
        // copy attribute
        TbTransAudit tbAuditInfo = new TbTransAudit();
        BeanUtils.copyProperties(transAuditInfo, tbAuditInfo);
        tbAuditInfo.setChainType(transAuditInfo.getChainType().byteValue());
        tbAuditInfo.setType(transAuditInfo.getType().byteValue());
        tbAuditInfo.setCreateTime(new Date());
        tbAuditInfo.setModifyTime(new Date());
        // save audit info
        int result = transAuditMapper.insertSelective(tbAuditInfo);
        if (result == 0) {
            log.warn("fail transAuditInfo after save.");
            throw new WebServerException(ConstantCode.SAVE_AUDIT_FAIL);
        }
        return getAuditInfoByTxHash(transAuditInfo.getTxHash());
    }

    /**
     * confirm transAuditInfo
     */
    public TbTransAudit confirmAuditInfo(Integer id) {
        if (!checkAuditInfoId(id)) {
            throw new WebServerException(ConstantCode.AUDIT_ID_NOT_EXISTS);
        }
        transAuditMapper.modifyStatus(id, AuditStatus.HANDLED.getValue());
        return getAuditInfoById(id);
    }

    /**
     * get transAuditInfo count
     */
    public int getAuditInfoCount(TbTransAuditExample example) {
        Integer count = (int) transAuditMapper.countByExample(example);
        return count == null ? 0 : count;
    }

    /**
     * get transAuditInfo list
     */
    public List<TbTransAudit> getAuditInfoList(TbTransAuditExample example) {
        return transAuditMapper.selectByExample(example);
    }

    /**
     * get audit info
     */
    public TbTransAudit getAuditInfoById(Integer id) {
        return transAuditMapper.selectByPrimaryKey(id);
    }

    /**
     * get audit info
     */
    public TbTransAudit getAuditInfoByTxHash(String txHash) {
        return transAuditMapper.selectByTxHash(txHash);
    }

    /**
     * remove transAuditInfo
     */
    public void removeAuditInfo(Integer id) {
        TbTransAudit tbTransAudit = getAuditInfoById(id);
        if (tbTransAudit == null) {
            throw new WebServerException(ConstantCode.AUDIT_ID_NOT_EXISTS);
        }
        transAuditMapper.modifyStatus(id, AuditStatus.DELETED.getValue());
    }

    /**
     * check transAuditInfo id
     */
    private boolean checkAuditInfoId(Integer id) {
        TbTransAudit tbTransAudit = getAuditInfoById(id);
        if (tbTransAudit == null) {
            return false;
        }
        return true;
    }

}
